package com.weijian.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.weijian.common.pojo.CommonResult;
import com.weijian.config.ReportExcelProperties;
import com.weijian.dal.entity.Order;
import com.weijian.dal.entity.User;
import com.weijian.dal.vo.*;
import com.weijian.mapper.ReportMapper;
import com.weijian.service.OrderService;
import com.weijian.service.ReportService;
import com.weijian.service.UserService;
import com.weijian.service.WorkspaceService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
@RequiredArgsConstructor
public class ReportServiceImpl implements ReportService {

    final OrderService orderService;

    final UserService userService;

    final WorkspaceService workspaceService;

    final ReportExcelProperties reportExcelProperties;

    final ReportMapper reportMapper;

    /**
     * 营业额统计
     */
    @Override
    @Tool(description = "统计某段时间内的营业额情况")
    public CommonResult<TurnoverReportVO> getTurnoverStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getLocalDates(begin, end);
        List<Double> countList = new ArrayList<>();
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            orderService.lambdaQuery()
                    .between(Order::getPayTime, beginTime, endTime)
                    .list()
                    .forEach(order -> {
                        countList.add(Double.valueOf(order.getTotalFee()));
                    });
        }
        TurnoverReportVO reportVO = TurnoverReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .turnoverList(StringUtils.join(countList, ",")).build();
        return CommonResult.success(reportVO);
    }

    /**
     * 用户统计
     */
    @Override
    @Tool(description = "统计某段时间内的用户情况")
    public CommonResult<UserReportVO> userStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getLocalDates(begin, end);
        List<Long> user = new ArrayList<>();
        List<Long> newUser = new ArrayList<>();
        for (LocalDate dateTime : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(dateTime, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(dateTime, LocalTime.MAX);
            Long sum = userService.lambdaQuery().between(User::getCreateTime, beginTime, endTime).count();
            Long sumUser = userService.lambdaQuery().le(User::getCreateTime, endTime).count();
            newUser.add(sum);
            user.add(sumUser);
        }
        UserReportVO reportVO = UserReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .totalUserList(StringUtils.join(user, ","))
                .newUserList(StringUtils.join(newUser, ","))
                .build();
        return CommonResult.success(reportVO);
    }

    /**
     * 完成的订单统计
     */
    @Override
    @Tool(description = "统计某段时间内的订单情况")
    public CommonResult<OrderReportVO> orderStatistics(LocalDate begin, LocalDate end) {
        List<LocalDate> dateList = getLocalDates(begin, end);
        ArrayList<Integer> orderCountList = new ArrayList<>();
        ArrayList<Integer> validOrderCountList = new ArrayList<>();
        int totalOrderCount = 0;
        int validOrderCount = 0;
        for (LocalDate date : dateList) {
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
            Long count = orderService.lambdaQuery()
                    .between(Order::getCreateTime, beginTime, endTime)
                    .count();
            orderCountList.add(count.intValue());
            Long validCount = orderService.lambdaQuery()
                    .between(Order::getPayTime, beginTime, endTime)
                    .count();
            validOrderCountList.add(validCount.intValue());
            totalOrderCount += count.intValue();
            validOrderCount += validCount.intValue();
        }
        Double rate = Math.round(validOrderCount * 100.0 / totalOrderCount * 100) / 100.0;

        OrderReportVO reportVO = OrderReportVO.builder()
                .dateList(StringUtils.join(dateList, ","))
                .orderCountList(StringUtils.join(orderCountList, ","))
                .validOrderCountList(StringUtils.join(validOrderCountList, ","))
                .totalOrderCount(totalOrderCount)
                .validOrderCount(validOrderCount)
                .orderCompletionRate(rate)
                .build();
        return CommonResult.success(reportVO);
    }

    /**
     * 销售前10
     */
    @Override
    @Tool(description = "统计某段时间内销量排名前十的菜品")
    public CommonResult<SalesTop10ReportVO> salesTop10Report(LocalDate begin, LocalDate end) {
        ArrayList<LocalDate> dateList = getLocalDates(begin, end);
        ArrayList<String> nameList = new ArrayList<>();
        ArrayList<String> numberList = new ArrayList<>();
        for (LocalDate date : dateList) {
            List<HashMap<String, Object>> result = reportMapper.salesTop10Report(LocalDateTime.of(date, LocalTime.MIN), LocalDateTime.of(date, LocalTime.MAX));
            for (HashMap<String, Object> map : result) {
                nameList.add(map.get("name").toString());
                numberList.add(map.get("number").toString());
            }
        }
        SalesTop10ReportVO reportVO = SalesTop10ReportVO.builder()
                .nameList(StringUtils.join(nameList, ","))
                .numberList(StringUtils.join(numberList, ","))
                .build();
        return CommonResult.success(reportVO);
    }

    /**
     * 导出excel表格（EasyExcel版）
     */
    @Override
    public void export(HttpServletResponse httpResponse) throws IOException {
        // 1. 准备模板文件路径
        String templatePath = reportExcelProperties.getFilePath();

        // 2. 准备数据
        LocalDateTime begin = LocalDateTime.now().with(TemporalAdjusters.firstDayOfMonth()).with(LocalTime.MIN);
        LocalDateTime end = LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth()).with(LocalTime.MAX);
        BusinessDataVO summaryData = workspaceService.getBusinessData(begin, end);
        log.info("summaryData: {}", summaryData);

        // 3. 准备明细数据
        int dayOfMonth = Period.between(begin.toLocalDate(), end.toLocalDate()).getDays();
        List<BusinessDataVO> detailDataList = new ArrayList<>();
        for (int i = 0; i < dayOfMonth; i++) {
            LocalDateTime dayBegin = begin.plusDays(i);
            BusinessDataVO businessData = workspaceService.getBusinessData(dayBegin, dayBegin.with(LocalTime.MAX));
            businessData.setDate(dayBegin.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日")));
            detailDataList.add(businessData);
        }

        // 4. 设置响应头
        httpResponse.setContentType("application/vnd.ms-excel");
        httpResponse.setHeader("Content-disposition", "attachment;filename=template.xlsx");

        // 5. 使用模板导出
        ExcelWriter excelWriter = EasyExcel.write(httpResponse.getOutputStream())
                .withTemplate(templatePath)
                .build();

        WriteSheet writeSheet = EasyExcel.writerSheet(reportExcelProperties.getSheet()[0]).build();

        // 6. 填充模板数据
        Map<String, Object> summaryMap = new HashMap<>();
        summaryMap.put("dateRange", begin.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss")) + "——" +
                end.format(DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss")));
        summaryMap.put("turnover", summaryData.getTurnover());
        summaryMap.put("completionRate", summaryData.getOrderCompletionRate());
        summaryMap.put("newUsers", summaryData.getNewUsers());
        summaryMap.put("validOrderCount", summaryData.getValidOrderCount());
        summaryMap.put("unitPrice", summaryData.getUnitPrice());
        log.info("summaryMap: {}", summaryMap);

//        excelWriter.fill(summaryMap, writeSheet);
//        excelWriter.fill(detailDataList, writeSheet);
        String currentPath = "src/test/java/com/weijian/excel/";
        // 拼接文件名
        String fileName = currentPath + "simpleWrite-" + System.currentTimeMillis() + ".xlsx";
        EasyExcel.write(fileName, BusinessDataVO.class)
                .sheet("1")
                .doWrite(detailDataList);


        // 7. 关闭资源
        excelWriter.finish();
    }

    //注意这段代码是包左也包右的
    @NotNull
    private static ArrayList<LocalDate> getLocalDates(LocalDate begin, LocalDate end) {
        LocalDate tmp = begin;
        ArrayList<LocalDate> dateList = new ArrayList<>();
        while (!tmp.isAfter(end)) {
            dateList.add(tmp);
            tmp = tmp.plusDays(1);
        }
        return dateList;
    }


}
